﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using umbraco.IO;

namespace TheOutfield.UmbExt.PageNotifications
{
    public class Config
    {
        #region Singleton

        private static Config _instance;

        public static Config Instance
        {
            get { return _instance ?? (_instance = new Config()); }
        }

        private Config()
        {
            InitConfig();
        }

        #endregion

        public List<Notification> Notifications { get; set; }

        private void InitConfig()
        {
            Notifications = new List<Notification>();

            var xmlConfig = new XmlDocument();
            xmlConfig.Load(IOHelper.MapPath(Path.Combine(SystemDirectories.Config, "pageNotifications.config")));
            var xmlConfigEntry = xmlConfig.SelectSingleNode("/pageNotifications");
            if (xmlConfigEntry == null)
                return;

            foreach (XmlNode xmlNotificationEntry in xmlConfigEntry.SelectNodes("notification"))
            {
                if (xmlNotificationEntry.NodeType == XmlNodeType.Element)
                {
                    var notification = new Notification
                    {
                        Type = (NotificationType)Enum.Parse(typeof(NotificationType), xmlNotificationEntry.Attributes["type"].Value)
                    };

                    foreach (XmlNode xmlMessageEntry in xmlNotificationEntry.SelectNodes("message"))
                    {
                        if (xmlMessageEntry.NodeType == XmlNodeType.Element)
                        {
                            var lang = xmlMessageEntry.Attributes["lang"].Value.ToLower();
                            if (!notification.Messages.ContainsKey(lang))
                                notification.Messages.Add(lang, xmlMessageEntry.InnerText);
                            else
                                notification.Messages[lang] = xmlMessageEntry.InnerText;
                        }
                    }

                    foreach (XmlNode xmlIndicatorBarEntry in xmlNotificationEntry.SelectNodes("environmentIndicator"))
                    {
                        foreach (XmlNode xmlUserTypeEntry in xmlIndicatorBarEntry.SelectNodes("userTypeAliases"))
                        {
                            if (xmlUserTypeEntry.NodeType != XmlNodeType.Element) continue;

                            foreach (var userTypeAlias in xmlUserTypeEntry.InnerText.Split(','))
                            {
                                var alias = userTypeAlias;
                                notification.IndicatorBar.UserTypeAliases.Add(alias);
                            }
                        }

                        foreach (XmlNode xmlIndicatorBars in xmlIndicatorBarEntry.SelectNodes("bar"))
                        {
                            if (xmlIndicatorBars.NodeType != XmlNodeType.Element) continue;

                            notification.IndicatorBar.Bars.Add(xmlIndicatorBars.Attributes["environment"].Value, xmlIndicatorBars.Attributes["color"].Value);
                        }
                    }
                    
                    foreach (XmlNode xmlIndicatorBarEntry in xmlNotificationEntry.SelectNodes("warning"))
                    {
                        foreach (XmlNode xmlUserTypeEntry in xmlIndicatorBarEntry.SelectNodes("userTypeAliases"))
                        {
                            if (xmlUserTypeEntry.NodeType != XmlNodeType.Element) continue;

                            foreach (var userTypeAlias in xmlUserTypeEntry.InnerText.Split(','))
                            {
                                var alias = userTypeAlias;
                                notification.SaveWarning.UserTypeAliases.Add(alias);
                            }
                        }

                        foreach (XmlNode xmlEnvironmentEntry in xmlIndicatorBarEntry.SelectNodes("environments"))
                        {
                            if (xmlEnvironmentEntry.NodeType != XmlNodeType.Element) continue;

                            foreach (var userTypeAlias in xmlEnvironmentEntry.InnerText.Split(','))
                            {
                                var alias = userTypeAlias;
                                notification.SaveWarning.Environments.Add(alias);
                            }
                        }
                    }

                    Notifications.Add(notification);
                }
            }
        }
    }

    public class Notification
    {
        public NotificationType Type { get; set; }
        public Dictionary<string, string> Messages { get; set; }
        public IndicatorBar IndicatorBar { get; set; }
        public SaveWarning SaveWarning { get; set; }

        public Notification()
        {
            Messages = new Dictionary<string, string>();
            IndicatorBar = new IndicatorBar();
            SaveWarning = new SaveWarning();
        }
    }

    public class IndicatorBar
    {
        public Dictionary<string, string> Bars { get; set; }
        public List<string> UserTypeAliases;

        public IndicatorBar()
        {
            Bars = new Dictionary<string, string>();
            UserTypeAliases = new List<string>();
        }
    }

    public class SaveWarning
    {
        public List<string> UserTypeAliases;
        public List<string> Environments;

        public SaveWarning()
        {
            UserTypeAliases = new List<string>();
            Environments = new List<string>();
        }
    }

    public enum NotificationType
    {
        Redirect,
        InternalRedirect,
        NaviHide,
        UnPublished,
        NoTemplate,
        Environment,
        SaveWarning
    }
}